package org.xtense.rcp.util;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.eclipse.jface.viewers.TreeViewer;
import org.xtense.data.DBConfig;
import org.xtense.data.DBManager;
import org.xtense.engine.IXmlReader;
import org.xtense.engine.actions.StoreAction;
import org.xtense.engine.actions.XAction;
import org.xtense.log.iLog;
import org.xtense.rcp.editors.util.XmlEntry;


public class XmlTreeUtil {

	public static String createXMLTree(TreeViewer tv, String path) {
		if (path == null) {
			return null;
		} else {
			iLog.info("Reading from path:" + path);
			File file = new File(path);
			try {
				SAXReader reader = new SAXReader();
				
				Document document = reader.read(file);
				Element root = document.getRootElement();
				tv.setInput(new Object[] { getXmlEntry(root) });
			} catch (DocumentException e) {
				e.printStackTrace();
			}
			iLog.info("Finish reading.");
			return file.getName();
		}
	}
	
	public static void createXmlTree(TreeViewer tv, List<Node> list) {
		List<XmlEntry> re = new ArrayList<XmlEntry>();
		Iterator<Node> itr = list.iterator();
		while(itr.hasNext()) {
			re.add(getXmlEntry(itr.next()));
		}
		tv.setInput(re.toArray());
	}
	
	public static void saveXMLTree(TreeViewer tv,String path) {
		Object input = tv.getInput();
		if(input instanceof Object[]) {
			XmlEntry entry = (XmlEntry)((Object[])input)[0];
			IXmlReader reader = new XmlEditorReader(entry,path);
			OutputStream fileOutputStream;
			try {
				iLog.info("Saving document to path:" + path);
				File f= new File(path);
				if(!f.exists()) {
					f.createNewFile();
				}
				fileOutputStream = new FileOutputStream(path);
				reader.read().compactWrite(fileOutputStream);
				fileOutputStream.flush();
				fileOutputStream.close();
				iLog.info("Finish saving.");
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
	}

	@SuppressWarnings("unchecked")
	private static XmlEntry getXmlEntry(Node node) {
		XmlEntry entry = new XmlEntry(node.getName());
		if (node instanceof Element) {
			Element element = (Element) node;
			entry.setType(XmlEntry.Element);
			entry.setValue(element.getTextTrim());
			entry.setPath(element.getPath());
			Iterator<Node> i = element.attributeIterator();
			while (i.hasNext()) {
				entry.addChild(getXmlEntry(i.next()));
			}
			i = element.elementIterator();
			while (i.hasNext()) {
				entry.addChild(getXmlEntry(i.next()));
			}
		} else if (node instanceof Attribute) {
			Attribute attribute = (Attribute) node;
			entry.setType(XmlEntry.Attribute);
			entry.setValue(attribute.getValue());
		}
		entry.setNode(node);
		return entry;
	}
	
	public static void storeXml(TreeViewer tv, String name) {
		Object input = tv.getInput();
		if(input instanceof Object[]) {
			XmlEntry entry = (XmlEntry)((Object[])input)[0];
			IXmlReader reader = new XmlEditorReader(entry,name);
			XAction saver = new StoreAction(new DBManager(DBConfig
					.getInstance(false, null)), name);
			saver.execute(reader.read());
		}
	}
}
